#ifndef TIMER_BOX_H_JM_20120720
#define TIMER_BOX_H_JM_20120720

// ##
#include "RootBox.h"
// ## C++
#include <iostream>
// ## bobox
#include <upp_mthr.hpp>

#include <bobox_box.hpp>
#include <bobox_types.hpp>


namespace jm4bbx {

	class Timer {
	public:
		void time() {
			static bool firstCall = true;
			
			ulibpp::uUINT64 lastTime = ulibpp::system_info::get_relative_time();
			if (firstCall) {
				firstCall = false;
			}
			else {
				std::cout<< "Time>>> " << (lastTime - actTime_) << std::endl;
			}

			actTime_ = lastTime;
		}
	private:
		ulibpp::uUINT64 actTime_;
	};

	struct TimerBoxDescriptor {
		//static const char* BOX_ID;
		static const  groupType INPUT_GROUP;
		static const  groupType OUTPUT_GROUP;	
		static const  columnType INPUT_COLUMN;
		static const  columnType OUTPUT_COLUMN;
		static const  inType IN_ARC;
		static const  bobox::outarc_index_type OUT_ARC;
	};

	class TimerBox : public Box/*<TimerBoxDescriptor>*/ {
	public:

		typedef TimerBoxDescriptor BoxIO;

		TimerBox(bobox::box_id_type id, bobox::box_tid_type tid, 
			bobox::request *req, const bobox::parameters &params) 
			: Box(id, tid, req, params) { }

		virtual void initImpl() override {


			add_group(BoxIO::OUTPUT_GROUP, 
				BoxIO::OUTPUT_COLUMN, 
				get_output_descriptors(BoxIO::OUT_ARC));


			add_group(BoxIO::INPUT_GROUP, 
				BoxIO::INPUT_COLUMN, 
				get_input_descriptors(BoxIO::IN_ARC));

			wait4Receive();
		}

		virtual void sync_mach_etwas() override {
			Group ig = get_group(BoxIO::INPUT_GROUP);
			if (ig.isPoisoned()/*poisoned_*/) {
				send_poisoned(BoxIO::OUT_ARC);
				return;
			}

			//size_t maxInedex = 0;
			//for (int i = 0; i < mergeFactor_; ++i) {
			//	maxInedex = std::max(maxInedex, get_group(BoxIO::getInGroup(i)).rdend_);
			//}
			//const group& og = get_group(BoxIO::OUTPUT_GROUP);
			//og.wrend_ = maxInedex;
			//og.wrpos_ = maxInedex;
			timer_.time();
			Group og = get_group(BoxIO::OUTPUT_GROUP);
			og.setWritePosition(ig.getReadEnd());//wrpos_ = ig.rdend_;
			og.setWriteEnd(ig.getReadEnd());//wrend_ = ig.rdend_;
			send(BoxIO::OUT_ARC, BoxIO::OUTPUT_GROUP);
			wait4Receive();
		}

	private:
		static Timer timer_;
		void wait4Receive() {
				receive(BoxIO::IN_ARC, BoxIO::INPUT_GROUP);
		}
	};


} // namespace jm4bbx

#endif
